/**
 * 
 */
package hanto.studentdlally.alpha;

import hanto.common.*;
import hanto.util.*;

/**
 * @author Doug Lally
 * @version Alpha
 *
 */
public class AlphaHantoGame implements HantoGame {

	private final HantoPlayerColor firstPlayer;
	private int nextMoveNumber;



	/**
	 * Construct a new AlphaHantoGame
	 */
	public AlphaHantoGame() {
		firstPlayer = HantoPlayerColor.BLUE;
		nextMoveNumber = 1;
		initialize(null);
	}

	/* (non-Javadoc)
	 * @see hanto.common.HantoGame#initialize(hanto.util.HantoPlayerColor)
	 */
	@Override
	public void initialize(HantoPlayerColor firstPlayer){
		// Blue is always first, so don't do anything

	}

	/* (non-Javadoc)
	 * @see hanto.common.HantoGame#makeMove(hanto.util.HantoPieceType, hanto.util.HantoCoordinate, hanto.util.HantoCoordinate)
	 */
	@Override
	public MoveResult makeMove(HantoPieceType pieceType, HantoCoordinate from,
			HantoCoordinate to) throws HantoException {
		//Make sure piece type is valid
		if(!isMoveValid(pieceType, from, to)){
			throw new HantoException("Invalid move");
		}

		nextMoveNumber++;
		return calculateMoveResult();
	}

	/**
	 * @return
	 */
	private MoveResult calculateMoveResult() {

		if(nextMoveNumber == 2){
			return MoveResult.OK;
		}
		else{
			return MoveResult.DRAW;
		}
	}

	/* (non-Javadoc)
	 * @see hanto.common.HantoGame#getPrintableBoard()
	 */
	@Override
	public String getPrintableBoard() {
		if(nextMoveNumber == 1){
			return "No moves made";
		}
		return "Blue has placed butterfly at [0,0]";

	}

	/**
	 * @return the firstPlayer
	 */
	public HantoPlayerColor getFirstPlayer() {
		return firstPlayer;
	}

	/**
	 * Checks to see if a move is valid within the current game state
	 * @param pieceType type of piece being played
	 * @param from former location of piece
	 * @param to destination of piece
	 * @return true if valid, false otherwise
	 */
	public boolean isMoveValid(HantoPieceType pieceType, HantoCoordinate from, HantoCoordinate to){
		//Pieces cannot move
		if(from != null){
			return false;
		}
		if(nextMoveNumber == 1){
			return !(pieceType != HantoPieceType.BUTTERFLY || from != null || to.getX() != 0 || to.getY() != 0);
		}
		if(nextMoveNumber == 2){
			if(pieceType != HantoPieceType.BUTTERFLY || from != null || (to.getX() == 0 && to.getY() == 0)){
				return false;
			}
			else if(!isAdjacent(new AlphaHantoCoordinate(0,0), to)){
				return false;
			}
			else{
				return true;
			}
		}
		// Not first or second move, what are you doing?
		return false;
	}

	/**
	 * Checks if two (valid) HantoCoordinates are adjacent in a hexagonal coordinate system
	 * @param first HantoCoordinate to check
	 * @param second HantoCoordinate
	 * @return true if they are adjacent, false otherwise
	 */
	private boolean isAdjacent(HantoCoordinate first,
			HantoCoordinate second) {
		// Case 1: directly above
		if(first.getX() == second.getX() && first.getY() + 1 == second.getY()){
			return true;
		}
		// Case 2: above and to right
		else if(first.getX() + 1 == second.getX() && first.getY() == second.getY()){
			return true;
		}
		// Case 3: below and to right
		else if(first.getX() + 1 == second.getX() && first.getY() - 1 == second.getY()){
			return true;
		}
		// Case 4: directly below
		else if(first.getX() == second.getX() && first.getY() - 1 == second.getY()){
			return true;
		}
		// Case 5: below and to left
		else if(first.getX() - 1 == second.getX() && first.getY() == second.getY()){
			return true;
		}
		// Case 6: above and to left
		else if(first.getX() - 1 == second.getX() && first.getY() + 1 == second.getY()){
			return true;
		}
		//Otherwise...
		return false;
	}
}

